// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

#ifndef AUTHORIZATION_H_
#define AUTHORIZATION_H_

#include <stdint.h>
#include <stddef.h>
#include "status/rot_status.h"


/**
 * Authorization manager for operations on the system.  This is only a mechanism for determining if
 * an operation is allowed to execute.  The operation itself will be executed independently.
 */
struct authorization {
	/**
	 * Determine if there is authorization within a given context.
	 *
	 * There are two ways in which this operation can be called:
	 *
	 * 1. A null token buffer.  This will check if the operation is allowed without any
	 * authorization.  If the operation is not allowed under any condition,
	 * AUTHORIZATION_NOT_AUTHORIZED will be returned.  If authorization is required,
	 * AUTHORIZATION_CHALLENGE will be returned and a token will be generated that must be signed to
	 * provide authorization for the operation.  The memory for the token is owned by the
	 * authorization context.
	 *
	 * 2. A non-null token buffer with an authorization token.  This will check for authorization
	 * based on the provided token.  If the token is not correct or the operation is not allowed,
	 * AUTHORIZATION_NOT_AUTHORIZED will be returned.  Nothing will be done with the token buffer
	 * provided to the call.  After a successful authorization, a new authorization token must be
	 * generated for additional authorization checks.
	 *
	 * @param auth The authorization manager to query.
	 * @param token Pointer to a buffer containing the authorization token.  The pointer itself
	 * cannot be null, but it can point to a null buffer.  In this case, no authentication data is
	 * being provided, and the call may generate an authorization token.  The output token will only
	 * be valid if AUTHORIZATION_CHALLENGE is returned.
	 * @param length The length of the authorization token.  If a token is allocated by the the
	 * call, this will be set to the length of the token.
	 *
	 * @return 0 if the operation is authorized or an error code.  If a token was generated,
	 * AUTHORIZATION_CHALLENGE will be returned.
	 */
	int (*authorize) (struct authorization *auth, uint8_t **token, size_t *length);
};


#define	AUTHORIZATION_ERROR(code)		ROT_ERROR (ROT_MODULE_AUTHORIZATION, code)

/**
 * Error codes that can be generated by an observer manager.
 */
enum {
	AUTHORIZATION_INVALID_ARGUMENT = AUTHORIZATION_ERROR (0x00),	/**< Input parameter is null or not valid. */
	AUTHORIZATION_NO_MEMORY = AUTHORIZATION_ERROR (0x01),			/**< Memory allocation failed. */
	AUTHORIZATION_AUTHORIZE_FAILED = AUTHORIZATION_ERROR (0x02),	/**< Could not determine authorization. */
	AUTHORIZATION_NOT_AUTHORIZED = AUTHORIZATION_ERROR (0x03),		/**< The operation is not authorized to execute. */
	AUTHORIZATION_CHALLENGE = AUTHORIZATION_ERROR (0x04),			/**< The requester must be challenged for authority. */
};


#endif /* AUTHORIZATION_H_ */
